﻿Imports System.IO
Imports System.Net
Imports System.Xml

Public Class Service

#Region "Declarations"
    Dim unit As Units = Units.Metric

    Dim obs As Observation

    Dim fcast As Forecast

    Dim Loc As WxLocation

    Dim lang As String

    Dim dayint As Integer

#End Region

#Region "Enums"
    Enum Units
        English
        Metric
    End Enum
#End Region

#Region "Properties"
    Public ReadOnly Property Observation As Observation
        Get
            Return obs
        End Get
    End Property

    Public ReadOnly Property Forecast As Forecast
        Get
            Return fcast
        End Get
    End Property
#End Region

#Region "Functions"

    Private Function GetCurrentConditions() As Observation
        Dim doc As New XmlDocument

        Select Case unit
            Case Units.English
                doc.Load(String.Format("http://wxdata.weather.com/wxdata/obs/{0}.xml?key=e88d3874-a740-102c-bafd-001321203584&locale={1}", Loc.LocationID, lang))

            Case Units.Metric
                doc.Load(String.Format("http://wxdata.weather.com/wxdata/obs/{0}.xml?key=e88d3874-a740-102c-bafd-001321203584&locale={1}&units=m", Loc.LocationID, lang))

        End Select

        Return New Observation(doc.SelectSingleNode("observation"))
    End Function

    Public Function GetForecast() As Forecast
        Dim ds As New DayCollection

        Dim doc As New XmlDocument

        Dim daylist As String = "0"

        For i As Integer = 1 To dayint
            daylist &= "," & i
            i += 1
        Next

        Select Case unit
            Case Units.English
                doc.Load(String.Format("http://wxdata.weather.com/wxdata/df/{0}.xml?key=e88d3874-a740-102c-bafd-001321203584&day={1}&locale={2}", Loc.LocationID, daylist, lang))

            Case Units.Metric
                doc.Load(String.Format("http://wxdata.weather.com/wxdata/df/{0}.xml?key=e88d3874-a740-102c-bafd-001321203584&day={1}&locale={2}&units=m", Loc.LocationID, daylist, lang))

        End Select

        For Each nod As XmlNode In doc.SelectNodes("/forecasts/forecast")
            ds.Add(New Day(nod))
        Next

        Return New Forecast(ds)
    End Function

    Public Shared Function SearchLocation(ByVal argument As String, ByVal locale As String) As WxLocationCollection
        Dim result As New WxLocationCollection

        Dim doc As New XmlDocument

        doc.Load(String.Format("http://wxdata.weather.com/wxdata/locsearch/{0}.xml?key=e88d3874-a740-102c-bafd-001321203584&locale={1}", argument, locale))

        For Each nod As XmlNode In doc.SelectNodes("/data/results/location")
            result.Add(New WxLocation(nod))
        Next

        Return result
    End Function

    Public Sub Update()
        obs = GetCurrentConditions()
        fcast = GetForecast()
    End Sub

#End Region

#Region "Constructor"
    Public Sub New(ByVal wxloc As WxLocation, ByVal daysInt As Integer, ByVal locale As String, ByVal selUnit As Units)
        unit = selUnit
        Loc = wxloc
        lang = locale
        dayint = daysInt
    End Sub
#End Region

End Class

Public Class DayPart
    Dim humid As String
    Public ReadOnly Property Humidity As String
        Get
            Return humid
        End Get
    End Property

    Dim ws As String
    Public ReadOnly Property WindSpeed As String
        Get
            Return ws
        End Get
    End Property

    Dim wd As String
    Public ReadOnly Property WindDirection As String
        Get
            Return wd
        End Get
    End Property

    Dim uv As String
    Public ReadOnly Property UVIndex As String
        Get
            Return uv
        End Get
    End Property

    Dim wxicon As String
    Public ReadOnly Property WeatherIcon As Integer
        Get
            Return wxicon
        End Get
    End Property

    Dim text As String
    Public ReadOnly Property Condition As String
        Get
            Return text
        End Get
    End Property

    Dim precip As String
    Public ReadOnly Property Precipitation As String
        Get
            Return precip
        End Get
    End Property

    Public Sub New(ByVal element As XmlElement)
        humid = element.SelectSingleNode("humid").InnerText
        ws = element.SelectSingleNode("wSpeed").InnerText
        wd = element.SelectSingleNode("wDirText").InnerText.Replace("<![CDATA[]]>", "")
        uv = element.SelectSingleNode("uv").InnerText
        wxicon = element.SelectSingleNode("icon").InnerText
        text = element.SelectSingleNode("phrase").InnerText.Replace("<![CDATA[]]>", "")
        precip = element.SelectSingleNode("snwAccumPhrase").InnerText
    End Sub
End Class

Public Class Day
    Dim vdate As New Date(1970, 1, 1)
    Public ReadOnly Property ValidDate As Date
        Get
            Return vdate
        End Get
    End Property

    Dim maxtemp As String
    Public ReadOnly Property MaxTemperature As String
        Get
            Return maxtemp
        End Get
    End Property

    Dim mintemp As String
    Public ReadOnly Property MinTemperature As String
        Get
            Return mintemp
        End Get
    End Property

    Dim day As DayPart
    Public ReadOnly Property DayTime As DayPart
        Get
            Return day
        End Get
    End Property

    Dim night As DayPart
    Public ReadOnly Property NightTime As DayPart
        Get
            Return night
        End Get
    End Property

    Public Sub New(ByVal element As XmlElement)
        vdate = New Date(1970, 1, 1).AddSeconds(element.SelectSingleNode("validDate").InnerText)

        If element.SelectSingleNode("day") IsNot Nothing Then
            day = New DayPart(element.SelectSingleNode("day"))
        End If

        If element.SelectSingleNode("night") IsNot Nothing Then
            night = New DayPart(element.SelectSingleNode("night"))
        End If

        maxtemp = element.SelectSingleNode("maxTemp").InnerText
        mintemp = element.SelectSingleNode("minTemp").InnerText
    End Sub
End Class

Public Class Forecast
    Dim days_ As DayCollection
    Public ReadOnly Property Days As DayCollection
        Get
            Return days_
        End Get
    End Property

    Public Sub New(ByVal days As DayCollection)
        days_ = days
    End Sub
End Class

Public Class DayCollection
    Inherits Collections.Generic.List(Of Day)
End Class

Public Class Observation
    Dim vdate As New Date(1970, 1, 1)
    Public ReadOnly Property ValidDate As Date
        Get
            Return vdate
        End Get
    End Property

    Dim wxicon As String
    Public ReadOnly Property WeatherIcon As String
        Get
            Return wxicon
        End Get
    End Property

    Dim visib As String
    Public ReadOnly Property Visibility As String
        Get
            Return visib
        End Get
    End Property

    Dim temp As String
    Public ReadOnly Property Temperature As String
        Get
            Return temp
        End Get
    End Property

    Dim tempMax24 As String
    Public ReadOnly Property MaxTemperature As String
        Get
            Return tempMax24
        End Get
    End Property

    Dim tempMin24 As String
    Public ReadOnly Property MinTemperature As String
        Get
            Return tempMin24
        End Get
    End Property

    Dim dewp As String
    Public ReadOnly Property DewPoint As String
        Get
            Return dewp
        End Get
    End Property

    Dim press As String
    Public ReadOnly Property Pressure As String
        Get
            Return press
        End Get
    End Property

    Dim pressDesc As String
    Public ReadOnly Property PressureDescription As String
        Get
            Return pressDesc
        End Get
    End Property

    Dim feelsl As String
    Public ReadOnly Property FeelsLike As String
        Get
            Return feelsl
        End Get
    End Property

    Dim humid As String
    Public ReadOnly Property Humidity As String
        Get
            Return humid
        End Get
    End Property

    Dim uv As String
    Public ReadOnly Property UvIndex As String
        Get
            Return uv
        End Get
    End Property

    Dim uvtext As String
    Public ReadOnly Property UvDescription As String
        Get
            Return uvtext
        End Get
    End Property

    Dim heatind As String
    Public ReadOnly Property HeatIndex As String
        Get
            Return heatind
        End Get
    End Property

    Dim windch As String
    Public ReadOnly Property WindChill As String
        Get
            Return windch
        End Get
    End Property

    Dim wnd As Wind
    Public ReadOnly Property Wind As Wind
        Get
            Return wnd
        End Get
    End Property

    Public Sub New(ByVal element As XmlElement)
        visib = element.SelectSingleNode("visibility").InnerText
        temp = element.SelectSingleNode("temp").InnerText
        tempMax24 = element.SelectSingleNode("tempMax24").InnerText
        tempMin24 = element.SelectSingleNode("tempMin24").InnerText
        dewp = element.SelectSingleNode("dewPoint").InnerText
        press = element.SelectSingleNode("pressure").InnerText
        pressDesc = element.SelectSingleNode("pressureDescription").InnerText
        feelsl = element.SelectSingleNode("feelsLike").InnerText
        humid = element.SelectSingleNode("humid").InnerText
        uv = element.SelectSingleNode("uv").InnerText
        uvtext = element.SelectSingleNode("uvText").InnerText
        heatind = element.SelectSingleNode("heatIndex").InnerText
        windch = element.SelectSingleNode("windchill").InnerText
        vdate = New Date(1970, 1, 1).AddSeconds(element.SelectSingleNode("date").InnerText)
        wxicon = element.SelectSingleNode("wxIcon").InnerText
        wnd = New Wind(element)
    End Sub

End Class

Public Class Wind
    Dim direction As String
    Public ReadOnly Property WindDirection As String
        Get
            Return direction
        End Get
    End Property

    Dim speed As String
    Public ReadOnly Property WindSpeed As String
        Get
            Return speed
        End Get
    End Property

    Dim gust As String
    Public ReadOnly Property Gusts As String
        Get
            Return gust
        End Get
    End Property
    Public Sub New(ByVal element As XmlElement)
        direction = element.SelectSingleNode("wDirText").InnerText
        speed = element.SelectSingleNode("wSpeed").InnerText
        gust = element.SelectSingleNode("wGust").InnerText
    End Sub
End Class

Public Class WxLocation
    Dim cty As String
    Public ReadOnly Property City As String
        Get
            Return cty
        End Get
    End Property

    Dim stat As String
    Public ReadOnly Property State As String
        Get
            Return stat
        End Get
    End Property

    Dim statName As String
    Public ReadOnly Property StateName As String
        Get
            Return statName
        End Get
    End Property

    Dim cntry As String
    Public ReadOnly Property Country As String
        Get
            Return cntry
        End Get
    End Property

    Dim parentLoc As String
    Public ReadOnly Property LocationID As String
        Get
            Return parentLoc
        End Get
    End Property

    Dim lat As String
    Public ReadOnly Property Latitude As String
        Get
            Return lat
        End Get
    End Property

    Dim lng As String
    Public ReadOnly Property Longitude As String
        Get
            Return lng
        End Get
    End Property

    Dim sel As String
    Public ReadOnly Property Selected As String
        Get
            Return sel
        End Get
    End Property

    Public Sub New(ByVal city As String, ByVal state As String, ByVal statename As String, ByVal country As String, ByVal wxId As String, ByVal latitude As String, ByVal longitude As String, ByVal selected As String)
        cty = city
        stat = state
        statName = statename
        cntry = country
        parentLoc = wxId
        lat = latitude
        lng = longitude
        sel = selected
    End Sub

    Public Sub New(ByVal element As XmlElement)
        stat = element.SelectSingleNode("state").InnerText
        statName = element.SelectSingleNode("stateName").InnerText
        cntry = element.SelectSingleNode("country").InnerText
        parentLoc = element.SelectSingleNode("parentLoc").InnerText
        lat = element.SelectSingleNode("lat").InnerText
        lng = element.SelectSingleNode("lng").InnerText
        cty = element.SelectSingleNode("city").InnerText.Replace("<![CDATA[]]>", "")
    End Sub
End Class

Public Class WxLocationCollection
    Inherits Collections.Generic.List(Of WxLocation)
End Class